<?php
/**
 * 苏宁支付智能代扣
 */
namespace App\Services;
use \phpseclib3\Crypt\RSA;

class SuningPayService
{

    /**
     * 生成签名
     * @param string 签名材料
     * @param string 签名编码（base64/hex/bin）
     * @return 签名值
     */
    const privateKey='MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDB5hyAwdOLTNTqFUpjFVo2x6o7LLHiKX0KbCtV4CHCP3P6Z5p8N+uWvkLn44T4gqH+JD+5VJSBfrVKrlCSF4tYiMTW8KkAGDQAyTyinBC+n2OSd/47/HPzyY74+YEMLiBd4k46Fg9IsJCNx+VNs2ON20MBRGBnC2DjALvCkTZWSC4Xh6s9A/SMGLeEDD6bkTZyTHG0r1mGJXgYs3iUX46R+yoEy7/RrNFaWEKuHl5aMywrnNJmpH4lV4845yI6CCjAq5Az+/34sP9dx7ivw5BLcY1LA0qdz+10G//8r/t1omQt5W1yQeKpptKuh+vh/pxk13MTITeMIvSzozZv4NiDAgMBAAECggEAOdgLAsJP+IuILPkDAwIYsqTn/NU9j+mumtBgMTM2/vrs/3Ou24XXK1ZBIWp3faeC6g0oUYKQ9vy02r2b3alWcagDiNesoxGVWfKuuxfxytxD2Ssg1gZfFQg5Nb9BJ0APedKMYbm4/4dk6FcM6hwtA+G4YIVkePklAzNxz/6ABkbmQLyei/O8Zwixx+0XbYBLRLiJ3at4Zccof2S4d+sOmCQ9IaRLPkV57tDl9hmuW/JzM01T1JhOBOY/lhGzndgaf3MnJTI4Oa0Z+tpC8CZfvV+U68nHWUH79Y5WcSGvXyEhqep098KJ2+5T/POH7Bmub8m8KruK+asfEpslswBkGQKBgQD7+h784yd0jRLtoX9Va0zBhA7NYrKdroqp3Wj0jHnVjs/XD/ZVXTx3Kh28/D4rFxNPRNO2zGkFmtGTD49KXxTPbHwpxK0nSauulbO/qsw2qyYqt3cpKHQotA86rIZqwrxFrrOlqllVI8uDFBgkrdtbp6y8kpS24x88Wi969oAzbwKBgQDE/p0UUb1HgwjePOncOxmJq9gGat/cVpHOcm1IMjkmlHz5cph3B94QXF7cY9POreUlzH/ETlnd836AgtYqK3tquTWqEtjDzbVvDi4PAwmNWcDLdEG6oY8viZaVryuj/RiFPpmyEXoLd6/C8b2IHy3xkRPF2vCzjb0RiTPvPuYSLQKBgBdxGIrsUxJbwYQL/z2iItzp/TqMUROsVkghSg9eNkNw6tMWMBOW/fYUG/ol+V6m4ewA+jVKZQbZdV/aFbmUiOoXLKHyIy3Bg9BVKwjMyfzYBU/6C4LvuYbD4ZrSzBqIjV1qOFpUM8Vg9CD4sJpQ9lRbkA1nEaDGFnTV6w7ked7PAoGAaEFH6IUJ41rZyqP6MG+mqFGl1l+hcf7u04+Dfn31+REEww9+2R/0yjvYiFLcubkWWNbNl5rPvMMs495acZ7phiXW3Nd0mMu5hbi/b3pwB7rEaehxENCH8uSiKT23nuZHn9ztgmv1ZzREdKtzXyMBMaNSD5g7YwtUUH+IWMm1AVECgYAqeLT7Z7U0f1Ye0kghhG07fax/nx9RSWmAAP818/LT4vXnaP5rG2YeuN4tQQfLMLZIylXh9fE4c3ffn2vCDEDHecViq9j7duhSoSf+LnNln4CmxkQR0nV79/dT4JrXDLLds//HLgPdb1f82kZ57X3H6n1WYWL8pB1xUhHold4e/Q==';
    const publicKey="MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAupgnMuASbbujp53BpuoSll0PoAPW3WmekdBzTtEDl6FEi+WwsT6bxJXpvbLH01esjYSBWBeBaLVoEl6HGMHlW3ieUHJ42MjjAYuh8KfosAikIC72tjMTvbF1p0fbDKWQk8QmQ8gfqN4MiPHV15PjWelig4Pd5SRzi3hr45Spx7BSlwyj0ng9IAHdH6OwRtJxWjJNMAefRsGPolwetv7BKv0gOsV78Se/GYL3JaN/FiGGBgNugyZ4TDJVeQrMe+bXg8dopEIqKGJj8224GEW/tgesx8MGj+HjXphox5YKn5czVylz6sPT0+wJ5a7LHZmIJC4Vwlm0ep9egacG5YU6OQIDAQAB";
    const host='https://mfg.suning.com';

    const APPID='yfbm71576140e2023072401';
    /**
     * * private key
     */
    private $_privKey;
    const salerMerchantNo='71576140';
    private $_pubKey;

    /**
     * * public key
     */
    public function __construct()
    {
        $this->setKey(self::publicKey,self::privateKey);
    }

  /**
   *协议支付签约申请接口
   */
    public static function agreementPaymentSign($bank){

        $encryptCardInfo['cardHolderName']=$bank['card_holder_name'];//持卡人姓名
        $encryptCardInfo['certType']='01';
        $encryptCardInfo['certNo']=$bank['cert_no'];//持卡人身份证号码

        $encryptCardInfo['mobileNo']=$bank['mobile_no'];//mobileNo
        $encryptCardInfo['cardNo']=$bank['card_no'];//mobileNo
        $encryptCardInfo['expYear']='18';//mobileNo
        $encryptCardInfo['expMonth']='08';//mobileNo
        $encryptCardInfo['cvv']='222';//mobileNo
        $encryptCardInfo['bankCode']=$bank['bank_code'];
        $encryptCardInfo['cardType']='DEBIT';//mobileNo
//        $encryptCardInfo['accountType']='PUBLICACCOUNT';//mobileNo


        $param['encryptCardInfo']=(new self())->pubEncrypt($encryptCardInfo);//加密后的卡信息包含：见下卡信息字段说明
        $param['merchantUserNo']=$bank['uid'];//用户在商户平台注册的帐号
        $param['salerMerchantNo']=self::salerMerchantNo;//传在易付宝申请的商户号
        $param['clientIp']=$_SERVER['REMOTE_ADDR'];//商户用户端的IP地址
        $param['goodsType']='711621';
        $param['sysName']='EPS';
        $param['productCode']='00010000674';
        $param['version']='2.3';
        $param['requestNo']=uniqid().time();
        $param['signTactics']='01';
//        $param['notifyUrl']='https://api.qianbaozuji.com/a';
//        $param['returnUrl']='https://api.qianbaozuji.com/b';
        $parameters = array(
            'appId' => self::APPID,//易付宝id
            'timestamp'=> date('YmdHis'),//时间
            'version'=>'1.0',//接口版本号
            'requestBody'=>json_encode($param),
        );
        $parameters['sign'] = (new self())->getSign($parameters);
        $parameters['signkeyIndex']='0001';
        $parameters['signType']='RSA2';

        $parameters=json_encode($parameters);
        $header=array('Content-Type:application/json');
        $result = http_post(self::host.'/ftpgs/ocps/agreementPayment/sign',$parameters,$header);
        $result=json_decode($result,true);
        return $result;
    }


    /**
     * 协议支付签约确认接口
     */
    public static function agreementPayGatewayConfirm($data){
   //加密后的卡信息包含：见下卡信息字段说明
        $param['msgId']=$data['msgId'];//短信序列号 签约申请成功时返回
        $param['productCode']='00010000674';//产品编码
        $param['requestNo']='12346'.rand('1000','9999').time();
        $param['salerMerchantNo']=self::salerMerchantNo;;//签约方商户
        $param['sysName']='eps';
        $param['verificationCode']=$data['verificationCode']; //短信验证码
        $param['version']='2.2';
        $param['clientIp']=$_SERVER['REMOTE_ADDR'];//商户用户端的IP地址
        $parameters = array(
            'appId' => self::APPID,//易付宝id
            'timestamp'=> date('YmdHis'),//时间
            'version'=>'1.0',//接口版本号
            'requestBody'=>json_encode($param),
        );
        $parameters['sign'] = (new self())->getSign($parameters);
        $parameters['signkeyIndex']='0001';
        $parameters['signType']='RSA2';

        $parameters=json_encode($parameters);
        $header=array('Content-Type:application/json');
        $result = http_post(self::host.'/ftpgs/ocps/agreementPayment/confirm',$parameters,$header);
        $result=json_decode($result,true);
        return $result;
    }


    /**
     * 协议支付接口
     */
    public static function agreementPaymentPay($data){
        //加密后的卡信息包含：见下卡信息字段说明
        $param['contractNo']=$data['contractNo'];
        $param['currency']='CNY';//短信序列号 签约申请成功时返回
        $param['goodsName']=$data['goodsName'];
        $param['goodsType']='711621';
        $param['notifyUrl']= config('alipay.callbackDomain').CommonService::NOTICE_WX_SUNING_PAY;
        $param['orderAmount']=bcmul($data['orderAmount'],100);
//        $param['orderExpireTime']=date('YmdHis',strtotime('+30 day'));
        $param['orderName']=$data['orderName'];
        $param['orderTime']=date('YmdHis');
        $param['outOrderNo']=$data['outOrderNo'];

        $param['productCode']='00010000674';//产品编码
        $param['requestNo']=$data['outOrderNo'].rand('1000','9999').time();
        $param['salerMerchantNo']=self::salerMerchantNo;//签约方商户
        $param['sysName']='EPPSEPS';
        $param['version']='2.2';
        $param['clientIp']=getRealIp();//商户用户端的IP地址
        $parameters = array(
            'appId' => self::APPID,//易付宝id
            'timestamp'=> date('YmdHis'),//时间
            'version'=>'1.0',//接口版本号
            'requestBody'=>json_encode($param),
        );
        $parameters['sign'] = (new self())->getSign($parameters);
        $parameters['signkeyIndex']='0001';
        $parameters['signType']='RSA2';

        $parameters=json_encode($parameters);
        $header=array('Content-Type:application/json');
        $result = http_post(self::host.'/ftpgs/ocps/agreementPayment/pay',$parameters,$header);
        return json_decode($result,true);
    }

    /**
     * 退款申请
     */
    public static function createRefundOrder($data){

        $param['submitTime']=date('YmdHis');
        $param['notifyUrl']=config('alipay.callbackDomain').CommonService::NOTICE_WX_SUNING_PAY;
        $param['version']='1.1';
        $param['refundOrderNo']=$data['refundOrderNo'];
        $param['origMerchantOrderNo']=$data['origMerchantOrderNo'];
        $param['origOutOrderNo']=$data['origOutOrderNo'];
        $param['origOrderTime']=date('YmdHis',$data['origOrderTime']);
        $param['refundOrderTime']=date('YmdHis');
        $param['refundAmount']=$data['refundAmount'];
        $param['operator']=$data['operator'];
        $param['refundReason']=$data['refundReason'];

        $parameters = array(
            'timestamp'=> date('YmdHis'),//时间
            'appId' => self::APPID,//易付宝id
            'version'=>'1.0',//接口版本号
            'requestBody'=>json_encode($param),
        );
        $parameters['sign'] = (new self())->getSign($parameters);
        $parameters['signkeyIndex']='0001';
        $parameters['signType']='RSA2';

        $parameters=json_encode($parameters);
        $header=array('Content-Type:application/json');
        $result = http_post(self::host.'/ftpgs/ocps/agreementPayment/createRefundOrder',$parameters,$header);
        return json_decode($result,true);
    }

    /**
     * 协议支付签约查询接口
     */
    public static function querySignAgreements(){

        $parameters = array(
            'appId' => self::APPID,//易付宝id
            'timestamp'=> date('YmdHis'),//时间
            'version'=>'1.0',//接口版本号
            'merchantUserNo'=>'123',
            'serialNo'=>time().rand(100,999)
        );
        $parameters['sign'] = (new self())->getSign($parameters);
        $parameters['signkeyIndex']='0001';
        $parameters['signType']='RSA2';


        $parameters=json_encode($parameters);
        var_dump($parameters);
        $header=array('Content-Type:application/json');
        $result = http_post(self::host.'/ftpgs/ocps/agreementPayment/querySignAgreements',$parameters,$header);
        return $result;
    }


    /**
     * 协议支付统一解约接口
     */
    public static function cancelContract($data){

        $param['contractNo']=$data['contractNo'];//签约协议号
        $param['productCode']='00010000674';//产品编码
        $parameters = array(
            'appId' => self::APPID,//易付宝id
            'timestamp'=> date('YmdHis'),//时间
            'version'=>'1.0',//接口版本号
            'requestBody'=>json_encode($param),
        );
        $parameters['sign'] = (new self())->getSign($parameters);
        $parameters['signkeyIndex']='0001';
        $parameters['signType']='RSA2';

        $parameters=json_encode($parameters);
        var_dump($parameters);
        $header=array('Content-Type:application/json');
        $result = http_post(self::host.'/ftpgs/ocps/agreementPayment/cancelContract',$parameters,$header);
        return $result;
    }

    /**
     * 查询商户订单
     */
    public static function queryMerchantOrder($data){
        $param['submitTime']=date('YmdHis');//签约协议号
        $param['version']='2.2';//签约协议号
        $param['outOrderNo']=$data['outOrderNo'];//订单号
        $param['orderTime']=time();//产品编码
        $parameters = array(
            'timestamp'=> date('YmdHis'),//时间
            'appId' => self::APPID,//易付宝id
            'version'=>'1.0',//接口版本号
            'requestBody'=>json_encode($param),
        );
        $parameters['sign'] = (new self())->getSign($parameters);
        $parameters['signkeyIndex']='0001';
        $parameters['signType']='RSA2';

        $parameters=json_encode($parameters);
        var_dump($parameters);
        $header=array('Content-Type:application/json');
        $result = http_post(self::host.'/ftpgs/ocps/agreementPayment/queryMerchantOrder',$parameters,$header);
        return $result;
    }



    /**
     * 查询退款订单
     */
    public static function queryRefundOrder($data){

        $param['submitTime']=date('YmdHis');//签约协议号
        $param['outOrderNo']=$data['outOrderNo'];//签约协议号
        $param['refundOrderTime']=$data['refundOrderTime'];
        $parameters = array(
            'timestamp'=> date('YmdHis'),//时间
            'appId' => self::APPID,//易付宝id
            'version'=>'1.0',//接口版本号
            'requestBody'=>json_encode($param),
        );
        $parameters['sign'] = (new self())->getSign($parameters);
        $parameters['signkeyIndex']='0001';
        $parameters['signType']='RSA2';

        $parameters=json_encode($parameters);
        var_dump($parameters);
        $header=array('Content-Type:application/json');
        $result = http_post(self::host.'/ftpgs/trade/queryOrder/queryRefundOrder',$parameters,$header);
        return $result;
    }

    /**
     * 设置公钥和私钥
     * @param string $publicKey  公钥
     * @param string $privateKey 私钥
     */
    public function setKey($publicKey=null,$privateKey = null)
    {
        if (!is_null($publicKey)) {
            $this->publicKey = $publicKey;
        }
        if (!is_null($privateKey)) {
            $this->privateKey = $privateKey;
        }
    }

    /**
     * * setup the private key
     */
    private function setupPrivKey()
    {
        if (is_resource($this->_privKey)) {
            return true;
        }
        $pem = chunk_split($this->privateKey, 64, "\n");
        $pem = "-----BEGIN PRIVATE KEY-----\n" . $pem . "-----END PRIVATE KEY-----\n";

        $this->_privKey = openssl_pkey_get_private($pem);
        return true;
    }

    /**
     * * setup the public key
     */
    private function setupPubKey()
    {
        if (is_resource($this->_pubKey)) {
            return true;
        }
        $pem = chunk_split($this->publicKey, 64, "\n");
        $pem = "-----BEGIN PUBLIC KEY-----\n" . $pem . "-----END PUBLIC KEY-----\n";
        $this->_pubKey = openssl_pkey_get_public($pem);
        return true;
    }


    /**
     * * encrypt with public key
     */
    public function pubEncrypt($data)
    {
        $dataString = json_encode($data);
//        // 加载公钥 并进行加密
        $this->setupPubKey();
        openssl_public_encrypt($dataString, $encodeStr,$this->_pubKey, OPENSSL_ZERO_PADDING);

        return strtoupper(bin2hex($encodeStr));

    }




    /**
     * 构造签名
     * @param string $dataString 被签名数据
     * @return string
     */
    public function sign($dataString)
    {
        $this->setupPrivKey();
        $signature = false;
        openssl_sign($dataString, $signature, $this->_privKey);
        return base64_encode($signature);//base64_encode($signature)
    }

    /**
     * 验证签名
     * @param string $dataString 被签名数据
     * @param string $signString 已经签名的字符串
     * @return number 1签名正确 0签名错误
     */
    public function verify($dataString, $signString)
    {
        $this->setupPubKey();
        $signature = base64_decode($signString);
        $flg = openssl_verify($dataString, $signature, $this->_pubKey);
        return $flg;
    }



    /*
 * 对要发送到微信统一下单接口的数据进行签名
 */
    protected function getSign($Obj){
        foreach ($Obj as $k => $v){
            $Parameters[$k] = $v;
        }
        //签名步骤一：按字典序排序参数
        ksort($Parameters);
        $String = $this->formatBizQueryParaMap($Parameters, false);
        //签名步骤三：MD5加密
        $String = md5($String);
        //签名步骤四：所有字符转为大写
        $result_ = strtoupper($String);
        return $this->sign($result_);
    }
    /*
     *排序并格式化参数方法，签名时需要使用
     */
    protected function formatBizQueryParaMap($paraMap, $urlencode)
    {
        $buff = "";
        ksort($paraMap);
        foreach ($paraMap as $k => $v)
        {
            if($urlencode)
            {
                $v = urlencode($v);
            }
            //$buff .= strtolower($k) . "=" . $v . "&";
            $buff .= $k . "=" . $v . "&";
        }
        $reqPar='';
        if (strlen($buff) > 0)
        {
            $reqPar = substr($buff, 0, strlen($buff)-1);
        }
        return $reqPar;
    }
    /*
     * 生成随机字符串方法
     */
    protected function createNoncestr($length = 32 ){
        $chars = "abcdefghijklmnopqrstuvwxyz0123456789";
        $str ="";
        for ( $i = 0; $i < $length; $i++ ) {
            $str.= substr($chars, mt_rand(0, strlen($chars)-1), 1);
        }
        return $str;
    }






}
